/*
 * // Bristleback plugin - Copyright (c) 2010 bristleback.googlecode.com
 * // ---------------------------------------------------------------------------
 * // This program is free software; you can redistribute it and/or modify it
 * // under the terms of the GNU Lesser General Public License as published by the
 * // Free Software Foundation; either version 3 of the License, or (at your
 * // option) any later version.
 * // This library is distributed in the hope that it will be useful,
 * // but without any warranty; without even the implied warranty of merchantability
 * // or fitness for a particular purpose.
 * // You should have received a copy of the GNU Lesser General Public License along
 * // with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
 * // ---------------------------------------------------------------------------
 */

package pl.bristleback.server.bristle.token;

import org.apache.log4j.Logger;
import org.jwebsocket.token.Token;
import pl.bristleback.server.bristle.exceptions.BristleTokenException;

import java.util.Map;

/**
 * Helper class, used to operate on token data.
 * <p/>
 * Created on: 2010-12-16 14:15:02 <br/>
 *
 * @author Wojciech Niemiec
 */
public class Tokenizer {
  private static Logger log = Logger.getLogger(Tokenizer.class.getName());

  private Map<Integer, TokenizerWrapper> tokenizerMap;
  private Map<String, TokenizerWrapper> namedTokenizerMap;

  /**
   * Adds values to given token.
   * Names of parameters for those values must be specified in {@link Tokenize} annotation,
   * located above this tokenizer field.
   * This method discovers which {@link Tokenize}
   * should be taken (by checking length of values array), name of parameter set is not used.
   *
   * @param token  a token to fill.
   * @param values values to add.
   * @return token given as parameter.
   */
  public Token tokenize(Token token, Object... values) {
    TokenizerWrapper tokenizer = tokenizerMap.get(values.length);
    if (tokenizer == null) {
      throw new BristleTokenException("No tokenizer found for fallowing number of parameters: " + values.length + ".");
    }
    tokenizer.tokenize(token, values);
    return token;
  }

  /**
   * Adds named values to given token.
   * Names of parameters for those values must be specified in {@link Tokenize} annotation,
   * located above this tokenizer field. This method makes use of tokenizing operation name, specified in in {@link Tokenize} annotation.
   *
   * @param token  a token to fill.
   * @param name   name of this token filling operation.
   * @param values values to add.
   * @return token given as parameter.
   */
  public Token tokenizeNamed(Token token, String name, Object... values) {
    TokenizerWrapper tokenizer = namedTokenizerMap.get(name);
    if (tokenizer == null) {
      throw new BristleTokenException("No tokenizer found for fallowing name: " + name + ".");
    }
    if (tokenizer.getParameterNames().length != values.length) {
      throw new BristleTokenException("Tokenizer with name: " + name + " expected fallowing number of values: " + tokenizer.getParameterNames().length
        + ", but got: " + values.length + ".");
    }
    tokenizer.tokenize(token, values);
    return token;
  }

  public Map<Integer, TokenizerWrapper> getTokenizerMap() {
    return tokenizerMap;
  }

  public Map<String, TokenizerWrapper> getNamedTokenizerMap() {
    return namedTokenizerMap;
  }

  public void setTokenizerMap(Map<Integer, TokenizerWrapper> tokenizerMap) {
    this.tokenizerMap = tokenizerMap;
  }

  public void setNamedTokenizerMap(Map<String, TokenizerWrapper> namedTokenizerMap) {
    this.namedTokenizerMap = namedTokenizerMap;
  }
}
